package br.com.toscano.gobra.domain;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cascade;

@Entity 
@Table(name="OBRA")
public class Obra  extends ObjetoAbstrato {

	private static final long serialVersionUID = 13454534543354513L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	@Column(name="OBRA_ID")
	private Long id;

	
	@ManyToOne(fetch = FetchType.LAZY, optional = true)
	@JoinColumn(name = "UNME_ID")
	private UnidadeMedida unidadeMedida;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = true)
	@JoinColumn(name = "STOB_ID")
	private SituacaoObra situacaoObra;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = true)
	@JoinColumn(name = "FOEX_ID")
	private FormaExecucao formaExecucao;

//	@ManyToOne(fetch = FetchType.LAZY, optional = false)
//	@JoinColumn(name = "TBPR_ID")
//	private TabelaPreco tabelaFontePrecos;		

	@ManyToOne(fetch = FetchType.LAZY, optional = true)
	@JoinColumn(name = "LICI_ID")
	private Licitacao licitacao;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "ESTA_UF")	
	private Estado ufEngenheiro;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "TPPR_ID")
	private TipoPrazo tipoPrazoObra;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "TPAR_ID")
	private TipoART tipoArt;

	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "UNOR_ID_ORCAMENTARIA")
	private UnidadeOrcamentaria unidadeOrcamentaria;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "UNOR_ID_EXECUTORA")
	private UnidadeOrcamentaria unidadeExecutora;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "PRAT_ID")
	private ProjetoAtividade projetoAtividade;
	
	@ManyToOne(fetch = FetchType.LAZY, optional = false)
	@JoinColumn(name = "DES_ID")
	private Despesa despesa;
	


	@Column(name="OBRA_CREA_ENGENHEIRO", nullable=false, length=255)
	private String creaEngenheiro;
	
	@Column(name="OBRA_NOME_ENGENHEIRO", nullable=false, length=255)
	private String nomeEngenheiro;
	
//	@Column(name="OBRA_CPF_ENGENHEIRO", nullable=false, length=255)
//	private String cpfEngenheiro;

	@Column(name="OBRA_NUMERO_ART", nullable=false, length=255)
	private String numeroArt;
	
	@Temporal(TemporalType.DATE)
	@Column(name = "OBRA_VALIDADE_ART", length = 7, nullable = false)
	private Date valiadeArt;

	@Column(name = "OBRA_VALOR_TOTAL_ITENS", nullable = false, precision = 19, scale = 2)
	private BigDecimal valorTotalItem;

	@Column(name="OBRA_TITULO", nullable=true, length=255)
	private String titulo;
	
	@Column(name="OBRA_LOCALIZACAO", nullable=true, length=255)
	private String localizacao;
	
	@Column(name = "OBRA_DIMENSAO_BASICA", nullable = false, precision = 19, scale = 2)
	private BigDecimal dimensaoBasica;
	
	@Column(name = "OBRA_ANO_EXERCICIO", precision = 4, scale = 0)
	private Long anoExercicio;
	
	@Column(name = "OBRA_DATA_CADASTRO", length = 7, nullable = false)
	private Date dataCadastro;
	
//	@Column(name = "OBRA_DATA_INICIO", length = 7, nullable = false)
//	private Date dataInicio;
//	
//	@Column(name = "OBRA_DATA_CONCLUSAO", length = 7, nullable = false)
//	private Date dataConclusao;
	
	@Column(name = "OBRA_VALOR_OBRA", nullable = false, precision = 19, scale = 2)
	private BigDecimal valorObra;
	
	@Column(name="OBRA_NUMERO_CEI", nullable=true, length=255)
	private String numeroCEI;
	
	@Column(name = "OBRA_DATA_VALIDADE_CEI", length = 7, nullable = true)
	private Date dataValidadeCEI;

	@Column(name = "OBRA_DATA_TERMO_CONCLUSAO_PROV", length = 7, nullable = true)
	private Date dataEmissaoTermoConclusaoProvisorio;		
	
	@Column(name = "OBRA_DATA_TERMO_CONCLUSAO_DEF", length = 7, nullable = true)
	private Date dataEmissaoTermoConclusaoDefinitivo;		

	@Column(name="OBRA_IND_DISPENSA_LICITACAO", nullable=true, length=255)
	private String indDispensaLicitacao;
	
	@Column(name="OBRA_FONTE_RECURSOS", nullable=true, length=255)
	private String fonteRecursos;
	
//	@Column(name="OBRA_TIPO_FONTE_RECURSOS", nullable=true, length=255)
//	private String tipoFonteRecursos;
	
	@Column(name="OBRA_NUM_CONVENIO_FONTE_RECURSOS", nullable=true, length=255)
	private String numeroConvenio;
	
	@Column(name="OBRA_NOME_ENTIDADE_FONTE_RECURSOS", nullable=true, length=255)
	private String nomeEntidade;
	
	@Column(name="OBRA_OBJ_CONVENIO_FONTE_RECURSOS", nullable=true, length=255)
	private String objetoConvenio;
	
	@Column(name = "OBRA_VALOR_TIPO_FONTE_RECURSOS", nullable = false, precision = 19, scale = 2)
	private BigDecimal valorTipoFonteRecursos;
	
	@Column(name = "OBRA_VALOR_REPASSE", nullable = false, precision = 19, scale = 2)
	private BigDecimal valorRepasse;
	
	@Column(name = "OBRA_PRAZO_EXECUCAO", precision = 4, scale = 0)
	private Long prazoExecucao;


	@OneToMany(fetch = FetchType.LAZY, mappedBy = "obra", orphanRemoval = true)
	@Cascade(value={org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.MERGE})
	@OrderBy(value="ordemExibicao")
	private List<ItemTabelaPrecoObra> listaItemTabelaPrecoObra;
	
	@ManyToMany(fetch = FetchType.LAZY)
	@JoinTable(name="OBRA_EXIGENCIA_TIPO_OBRA",
		joinColumns = @JoinColumn( name="OBRA_ID"),
		inverseJoinColumns = @JoinColumn( name="IETO_ID")
	)
//	@Cascade(value={org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.MERGE})
	private List<ExigenciaTipoObra> listaObraItemExigenciaTipoObra = new ArrayList<ExigenciaTipoObra>();

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "obra", orphanRemoval = true)
	@Cascade(value={org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.MERGE})
	private List<Anexo> listaDocumentosObra= new ArrayList<Anexo>();

//	@OneToMany(fetch = FetchType.LAZY, mappedBy = "obra", orphanRemoval = true)
//	@Cascade(value={org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.MERGE})
//	private List<ObraTipoAgrupamentoServico> listaObraTipoAgrupamentoServico = new ArrayList<ObraTipoAgrupamentoServico>();

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "obra")
	private List<BoletimMedicao> listaBoletimMedicao = new ArrayList<BoletimMedicao>();

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "obra", orphanRemoval = true)
	@Cascade(value={org.hibernate.annotations.CascadeType.PERSIST, org.hibernate.annotations.CascadeType.MERGE})
	private List<ComposicaoBDI> listaComposicaoBDI = new ArrayList<ComposicaoBDI>();
	
	public Long getId() {
		
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	public Estado getUfEngenheiro() {
		return ufEngenheiro;
	}

	public void setUfEngenheiro(Estado ufEngenheiro) {
		this.ufEngenheiro = ufEngenheiro;
	}

	public TipoPrazo getTipoPrazoObra() {
		return tipoPrazoObra;
	}

	public void setTipoPrazoObra(TipoPrazo tipoPrazoObra) {
		this.tipoPrazoObra = tipoPrazoObra;
	}

	public TipoART getTipoArt() {
		return tipoArt;
	}

	public void setTipoArt(TipoART tipoArt) {
		this.tipoArt = tipoArt;
	}

	public String getCreaEngenheiro() {
		return creaEngenheiro;
	}

	public void setCreaEngenheiro(String creaEngenheiro) {
		this.creaEngenheiro = creaEngenheiro;
	}

	public String getNomeEngenheiro() {
		return nomeEngenheiro;
	}

	public void setNomeEngenheiro(String nomeEngenheiro) {
		this.nomeEngenheiro = nomeEngenheiro;
	}

//	public String getCpfEngenheiro() {
//		return cpfEngenheiro;
//	}
//
//	public void setCpfEngenheiro(String cpfEngenheiro) {
//		this.cpfEngenheiro = cpfEngenheiro;
//	}
//
	public String getNumeroArt() {
		return numeroArt;
	}

	public void setNumeroArt(String numeroArt) {
		this.numeroArt = numeroArt;
	}

	public Date getValiadeArt() {
		return valiadeArt;
	}

	public void setValiadeArt(Date valiadeArt) {
		this.valiadeArt = valiadeArt;
	}

	public BigDecimal getValorTotalItem() {
		return valorTotalItem;
	}

	public void setValorTotalItem(BigDecimal valorTotalItem) {
		this.valorTotalItem = valorTotalItem;
	}

	public ProjetoAtividade getProjetoAtividade() {
		return projetoAtividade;
	}

	public void setProjetoAtividade(ProjetoAtividade projetoAtividade) {
		this.projetoAtividade = projetoAtividade;
	}

	public Despesa getDespesa() {
		return despesa;
	}

	public void setDespesa(Despesa despesa) {
		this.despesa = despesa;
	}

	public String getTitulo() {
		return titulo;
	}

	public void setTitulo(String titulo) {
		this.titulo = titulo;
	}

	public String getLocalizacao() {
		return localizacao;
	}

	public void setLocalizacao(String localizacao) {
		this.localizacao = localizacao;
	}

	public UnidadeOrcamentaria getUnidadeOrcamentaria() {
		return unidadeOrcamentaria;
	}

	public void setUnidadeOrcamentaria(UnidadeOrcamentaria unidadeOrcamentaria) {
		this.unidadeOrcamentaria = unidadeOrcamentaria;
	}

	public UnidadeOrcamentaria getUnidadeExecutora() {
		return unidadeExecutora;
	}

	public void setUnidadeExecutora(UnidadeOrcamentaria unidadeExecutora) {
		this.unidadeExecutora = unidadeExecutora;
	}

	public BigDecimal getDimensaoBasica() {
		return dimensaoBasica;
	}

	public void setDimensaoBasica(BigDecimal dimensaoBasica) {
		this.dimensaoBasica = dimensaoBasica;
	}

	public UnidadeMedida getUnidadeMedida() {
		return unidadeMedida;
	}

	public void setUnidadeMedida(UnidadeMedida unidadeMedida) {
		this.unidadeMedida = unidadeMedida;
	}

	public Long getAnoExercicio() {
		return anoExercicio;
	}

	public void setAnoExercicio(Long anoExercicio) {
		this.anoExercicio = anoExercicio;
	}

	public SituacaoObra getSituacaoObra() {
		return situacaoObra;
	}

	public void setSituacaoObra(SituacaoObra situacaoObra) {
		this.situacaoObra = situacaoObra;
	}

	public Date getDataCadastro() {
		return dataCadastro;
	}

	public void setDataCadastro(Date dataCadastro) {
		this.dataCadastro = dataCadastro;
	}

//	public Date getDataInicio() {
//		return dataInicio;
//	}
//
//	public void setDataInicio(Date dataInicio) {
//		this.dataInicio = dataInicio;
//	}
//
//	public Date getDataConclusao() {
//		return dataConclusao;
//	}
//
//	public void setDataConclusao(Date dataConclusao) {
//		this.dataConclusao = dataConclusao;
//	}
//
	public BigDecimal getValorObra() {
		return valorObra;
	}

	public void setValorObra(BigDecimal valorObra) {
		this.valorObra = valorObra;
	}

	public FormaExecucao getFormaExecucao() {
		return formaExecucao;
	}

	public void setFormaExecucao(FormaExecucao formaExecucao) {
		this.formaExecucao = formaExecucao;
	}

	public List<ItemTabelaPrecoObra> getListaItemTabelaPrecoObra() {
		return listaItemTabelaPrecoObra;
	}

	public void setListaItemTabelaPrecoObra(
			List<ItemTabelaPrecoObra> listaItemTabelaPrecoObra) {
		this.listaItemTabelaPrecoObra = listaItemTabelaPrecoObra;
	}

	public List<ExigenciaTipoObra> getListaObraItemExigenciaTipoObra() {
		return listaObraItemExigenciaTipoObra;
	}

	public void setListaObraItemExigenciaTipoObra(
			List<ExigenciaTipoObra> listaObraItemExigenciaTipoObra) {
		this.listaObraItemExigenciaTipoObra = listaObraItemExigenciaTipoObra;
	}

	public List<Anexo> getListaDocumentosObra() {
		return listaDocumentosObra;
	}

	public void setListaDocumentosObra(List<Anexo> listaDocumentosObra) {
		this.listaDocumentosObra = listaDocumentosObra;
	}

	public String getNumeroCEI() {
		return numeroCEI;
	}

	public void setNumeroCEI(String numeroCEI) {
		this.numeroCEI = numeroCEI;
	}

	public Date getDataValidadeCEI() {
		return dataValidadeCEI;
	}

	public void setDataValidadeCEI(Date dataValidadeCEI) {
		this.dataValidadeCEI = dataValidadeCEI;
	}

//	public TabelaPreco getTabelaFontePrecos() {
//		return tabelaFontePrecos;
//	}
//
//	public void setTabelaFontePrecos(TabelaPreco tabelaFontePrecos) {
//		this.tabelaFontePrecos = tabelaFontePrecos;
//	}

	public Date getDataEmissaoTermoConclusaoProvisorio() {
		return dataEmissaoTermoConclusaoProvisorio;
	}

	public void setDataEmissaoTermoConclusaoProvisorio(
			Date dataEmissaoTermoConclusaoProvisorio) {
		this.dataEmissaoTermoConclusaoProvisorio = dataEmissaoTermoConclusaoProvisorio;
	}

	public Date getDataEmissaoTermoConclusaoDefinitivo() {
		return dataEmissaoTermoConclusaoDefinitivo;
	}

	public void setDataEmissaoTermoConclusaoDefinitivo(
			Date dataEmissaoTermoConclusaoDefinitivo) {
		this.dataEmissaoTermoConclusaoDefinitivo = dataEmissaoTermoConclusaoDefinitivo;
	}

	public List<ComposicaoBDI> getListaComposicaoBDI() {
		return listaComposicaoBDI;
	}

	public void setListaComposicaoBDI(List<ComposicaoBDI> listaComposicaoBDI) {
		this.listaComposicaoBDI = listaComposicaoBDI;
	}

	public Licitacao getLicitacao() {
		return licitacao;
	}

	public void setLicitacao(Licitacao licitacao) {
		this.licitacao = licitacao;
	}

	public String getIndDispensaLicitacao() {
		return indDispensaLicitacao;
	}

	public void setIndDispensaLicitacao(String indDispensaLicitacao) {
		this.indDispensaLicitacao = indDispensaLicitacao;
	}

	public String getFonteRecursos() {
		return fonteRecursos;
	}

	public void setFonteRecursos(String fonteRecursos) {
		this.fonteRecursos = fonteRecursos;
	}

//	public String getTipoFonteRecursos() {
//		return tipoFonteRecursos;
//	}
//
//	public void setTipoFonteRecursos(String tipoFonteRecursos) {
//		this.tipoFonteRecursos = tipoFonteRecursos;
//	}
//
	public String getNumeroConvenio() {
		return numeroConvenio;
	}

	public void setNumeroConvenio(String numeroConvenio) {
		this.numeroConvenio = numeroConvenio;
	}

	public String getNomeEntidade() {
		return nomeEntidade;
	}

	public void setNomeEntidade(String nomeEntidade) {
		this.nomeEntidade = nomeEntidade;
	}

	public String getObjetoConvenio() {
		return objetoConvenio;
	}

	public void setObjetoConvenio(String objetoConvenio) {
		this.objetoConvenio = objetoConvenio;
	}

	public BigDecimal getValorTipoFonteRecursos() {
		return valorTipoFonteRecursos;
	}

	public void setValorTipoFonteRecursos(BigDecimal valorTipoFonteRecursos) {
		this.valorTipoFonteRecursos = valorTipoFonteRecursos;
	}

	public BigDecimal getValorRepasse() {
		return valorRepasse;
	}

	public void setValorRepasse(BigDecimal valorRepasse) {
		this.valorRepasse = valorRepasse;
	}

	public Long getPrazoExecucao() {
		return prazoExecucao;
	}

	public void setPrazoExecucao(Long prazoExecucao) {
		this.prazoExecucao = prazoExecucao;
	}

	public List<BoletimMedicao> getListaBoletimMedicao() {
		return listaBoletimMedicao;
	}

	public void setListaBoletimMedicao(List<BoletimMedicao> listaBoletimMedicao) {
		this.listaBoletimMedicao = listaBoletimMedicao;
	}
	


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if(!this.getClass().equals(obj.getClass()))
			return false;
		if (getClass() != obj.getClass())
			return false;
		Obra other = (Obra) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
}